from django.db import models
from django.utils import timezone
from staff.models import Employee
from datetime import timedelta, time


class AttendanceRecord(models.Model):
    """考勤记录模型，与员工模型通过外键关联"""
    STATUS_CHOICES = [
        ('正常', '正常'),
        ('迟到', '迟到'),
        ('早退', '早退'),
        ('缺上班卡', '缺上班卡'),
        ('缺下班卡', '缺下班卡'),
        ('旷工', '旷工'),
        ('请假', '请假'),
        ('出差', '出差'),
    ]

    # 与员工表关联（多对一关系）
    employee = models.ForeignKey(
        Employee,
        on_delete=models.CASCADE,
        related_name='attendance_records',
        verbose_name='员工'
    )
    record_date = models.DateField('考勤日期')

    # 实际打卡时间
    check_in_time = models.DateTimeField('上班打卡时间', null=True, blank=True)
    check_out_time = models.DateTimeField('下班打卡时间', null=True, blank=True)

    # 考勤状态及计算结果
    status = models.CharField('考勤状态', max_length=10, choices=STATUS_CHOICES, default='旷工')
    late_minutes = models.PositiveIntegerField('迟到分钟数', default=0)
    early_leave_minutes = models.PositiveIntegerField('早退分钟数', default=0)

    # 补卡相关标记
    is_corrected = models.BooleanField('是否补卡', default=False)
    correction_note = models.TextField('补卡备注', blank=True, null=True)

    # 系统字段
    status_updated_at = models.DateTimeField('状态更新时间', null=True, blank=True)
    created_at = models.DateTimeField('创建时间', auto_now_add=True)
    updated_at = models.DateTimeField('更新时间', auto_now=True)

    class Meta:
        verbose_name = '考勤记录'
        verbose_name_plural = '考勤记录'
        ordering = ['-record_date']
        unique_together = ['employee', 'record_date']
        indexes = [
            models.Index(fields=['employee', 'record_date']),
            models.Index(fields=['record_date']),
            models.Index(fields=['status']),
        ]

    def __str__(self):
        return f"{self.employee.name} {self.record_date} {self.status}"

    def calculate_status(self):
        weekday = self.record_date.weekday()  # 0=周一，4=周五，5=周六，6=周日
        if weekday >= 5:
            return

        # 固定考勤时间标准
        STANDARD_CHECKIN = time(9, 30)  # 上班时间9:30
        STANDARD_CHECKOUT = time(19, 0)  # 下班时间19:00

        # 构建带日期的标准时间（带时区）
        std_checkin = timezone.datetime.combine(
            self.record_date, STANDARD_CHECKIN
        ).replace(tzinfo=timezone.get_current_timezone())

        std_checkout = timezone.datetime.combine(
            self.record_date, STANDARD_CHECKOUT
        ).replace(tzinfo=timezone.get_current_timezone())

        # 检查打卡状态
        has_checkin = self.check_in_time is not None
        has_checkout = self.check_out_time is not None

        # 初始化状态
        self.status = '正常'
        self.late_minutes = 0
        self.early_leave_minutes = 0

        # 处理上班卡
        if not has_checkin:
            self.status = '缺上班卡'
        else:
            # 转换为本地时区比较
            checkin = self.check_in_time.astimezone(timezone.get_current_timezone())
            # 直接判断：大于9:30即为迟到
            if checkin > std_checkin:
                self.status = '迟到'
                self.late_minutes = int((checkin - std_checkin).total_seconds() / 60)

        # 处理下班卡
        if not has_checkout:
            # 如果已有迟到状态则保留，否则标记为缺下班卡
            if self.status == '正常':
                self.status = '缺下班卡'
        else:
            checkout = self.check_out_time.astimezone(timezone.get_current_timezone())
            # 小于19:00即为早退
            if checkout < std_checkout:
                # 如果已有迟到状态则保留，否则标记为早退
                if self.status == '正常':
                    self.status = '早退'
                self.early_leave_minutes = int((std_checkout - checkout).total_seconds() / 60)

        # 都没打卡则为旷工
        if not has_checkin and not has_checkout:
            self.status = '旷工'

        self.status_updated_at = timezone.now()
